import { ISpeechManager } from "../types/ISpeechManager";

/**
 * 语音管理器实现
 * 
 * 负责管理Web Speech API的语音合成功能
 * 提供文本转语音、语音控制等功能
 * 支持语音参数配置和状态管理
 */
export class SpeechManager implements ISpeechManager {
    /** Web Speech API的语音合成对象 */
    private speechSynthesis: SpeechSynthesis | null = null;
    
    /** 当前是否正在播放语音 */
    private _isSpeaking = false;
    
    /** 语音回调函数集合 */
    private callbacks: {
        onSpeechStart?: (text: string) => void;
        onSpeechEnd?: (text: string) => void;
        onError?: (error: string) => void;
    } = {};

    /**
     * 构造函数
     * 
     * @param callbacks 语音回调函数配置
     * - onSpeechStart: 语音开始时触发
     * - onSpeechEnd: 语音结束时触发
     * - onError: 语音错误时触发
     */
    constructor(callbacks?: {
        onSpeechStart?: (text: string) => void;
        onSpeechEnd?: (text: string) => void;
        onError?: (error: string) => void;
    }) {
        this.callbacks = callbacks || {};
        this.initSpeechSynthesis();
    }

    /**
     * 初始化语音合成功能
     * 
     * 功能：
     * 检查浏览器是否支持Web Speech API
     * 如果支持则初始化语音合成对象
     */
    private initSpeechSynthesis() {
        if ('speechSynthesis' in window) {
            this.speechSynthesis = window.speechSynthesis;
        }
    }

    /**
     * 播放语音
     * 
     * @param text 要播放的文本内容
     * @param options 语音参数配置
     * - voice: 语音名称
     * - rate: 语速 (0.1-10)
     * - pitch: 音调 (0-2)
     * - volume: 音量 (0-1)
     * @returns Promise<void> 语音播放完成
     * 
     * 功能：
     * 1. 检查语音合成是否可用
     * 2. 设置语音状态为播放中
     * 3. 触发语音开始回调
     * 4. 创建语音合成对象并配置参数
     * 5. 监听语音播放完成和错误事件
     * 6. 开始播放语音
     */
    async speak(
        text: string, 
        options: {
            voice?: string;
            rate?: number;
            pitch?: number;
            volume?: number;
        } = {}
    ): Promise<void> {
        // 检查语音合成是否可用或已在播放
        if (!this.speechSynthesis || this._isSpeaking) return;

        this._isSpeaking = true;
        this.callbacks.onSpeechStart?.(text);

        return new Promise((resolve) => {
            // 创建语音合成对象
            const utterance = new SpeechSynthesisUtterance(text);
            
            // 设置语音参数
            utterance.rate = options.rate || 1;
            utterance.pitch = options.pitch || 1;
            utterance.volume = options.volume || 1;
            
            // 设置语音类型
            if (options.voice && this.speechSynthesis) {
                const voices = this.speechSynthesis.getVoices();
                const voice = voices.find(v => v.name === options.voice);
                if (voice) {
                    utterance.voice = voice;
                }
            }

            // 监听语音播放完成
            utterance.onend = () => {
                this._isSpeaking = false;
                this.callbacks.onSpeechEnd?.(text);
                resolve();
            };

            // 监听语音播放错误
            utterance.onerror = (error) => {
                this._isSpeaking = false;
                // 忽略中断错误，这是正常的停止操作
                if (error.error !== 'interrupted') {
                    this.callbacks.onError?.(`语音合成失败: ${error.error}`);
                }
                resolve();
            };

            // 开始播放语音
            if (this.speechSynthesis) {
                this.speechSynthesis.speak(utterance);
            }
        });
    }

    /**
     * 停止语音播放
     * 
     * 功能：
     * 1. 检查是否正在播放语音
     * 2. 取消当前语音播放
     * 3. 设置语音状态为停止
     * 4. 触发语音结束回调
     */
    stopSpeaking(): void {
        if (this.speechSynthesis && this._isSpeaking) {
            try {
                this.speechSynthesis.cancel();
            } catch (error) {
                console.warn('停止语音时出错:', error);
            }
            this._isSpeaking = false;
            this.callbacks.onSpeechEnd?.('stopped');
        }
    }

    /**
     * 检查是否正在播放语音
     * 
     * @returns boolean 是否正在播放语音
     */
    isSpeaking(): boolean {
        return this._isSpeaking;
    }
} 